﻿# -*- coding: utf-8 -*-

import pygame, sys
from pygame.locals import *

try:
    import pygame.fastevent as eventmodule
except ImportError:
    import pygame.event as eventmodule

import clientNetwork
from netDefines import *

WINDOWSIZE = width, height = 640, 480

CBLACK = (0, 0, 0)
CWHITE = (255, 255, 255)

QUIT_KEY = 27
SELECT_KEY = 122
CANCEL_KEY = 120
UP_KEY = 273
DOWN_KEY = 274
RIGHT_KEY = 275
LEFT_KEY = 276
PLUS_KEY = 270
MINUS_KEY = 269

FONT_WIDTH = 9
FONT_HEIGHT = 17
FONT_SIZE = width, height = FONT_WIDTH, FONT_HEIGHT
DISP_WIDTH = 42
DISP_HEIGHT = 28
DISP_TOTAL = DISP_WIDTH*DISP_HEIGHT
DISP_SCREEN = width, height = DISP_WIDTH*FONT_WIDTH, DISP_HEIGHT*FONT_HEIGHT

pygame.init()
if hasattr(eventmodule, 'init'):
    eventmodule.init()
taskicon = pygame.Surface((32, 32))
taskiconfile = pygame.image.load("taskicon.bmp")
taskicon.blit(taskiconfile, (0, 0, 32, 32))
pygame.display.set_icon(taskicon)
pygame.display.set_caption('The Sixth Realm')

screen = pygame.display.set_mode(WINDOWSIZE)
TheClock = pygame.time.Clock()

displayClearer = pygame.Surface(DISP_SCREEN)
displayClearer = displayClearer.convert()
displayClearer.fill(CBLACK)

textBG = pygame.Surface(FONT_SIZE)
textBG = textBG.convert()

dispfont = pygame.font.Font("DejaVuMonoSans.ttf", 14)

class globalStuff():
    
    def __init__(self):
        self.cursor = [0, 0, 0]
        self.camera = [0, 0, 0]
        self.needFlip = False
        self.currentDisplay = [(' ', 0, 0, 0, 0, 0, 0)]*DISP_TOTAL

glob = globalStuff()

def processRawDisplay(input):
    print len(input)
    print DISP_TOTAL*19
    if len(input) == DISP_TOTAL*19:
        result = []
        for i, char in enumerate(input[0:DISP_TOTAL]):
            x = (i*9)+DISP_TOTAL
            n = x+(DISP_TOTAL*9)
            result.append((char, 
                           int(input[x:x+3]), int(input[x+3:x+6]), int(input[x+6:x+9]),
                           int(input[n:n+3]), int(input[n+3:n+6]), int(input[n+6:n+9])))
        return result
    #else:
    #    result = []
    #    for i, char in enumerate(input[0:(len(input)/10)]):
    #        x = (i*9)+(len(input)/10)
    #        result.append((char, int(input[x:x+3]), int(input[x+3:x+6]), int(input[x+6:x+9])))
    #    result = result + [(u"█", 0, 0, 0)]*(DISP_TOTAL-len(result))
    #    return result

def renderDisplay():
    screen.blit(displayClearer, (0, 0))
    for pos, chardat in enumerate(glob.currentDisplay):
        textBG.fill(chardat[4:])
        screen.blit(textBG, ((pos%DISP_WIDTH)*FONT_WIDTH, (pos/DISP_WIDTH)*FONT_HEIGHT))
        screen.blit(dispfont.render(chardat[0], 1, chardat[1:4], chardat[4:]), ((pos%DISP_WIDTH)*FONT_WIDTH, (pos/DISP_WIDTH)*FONT_HEIGHT))
    textBG.fill((40, 255, 40))
    screen.blit(textBG, (glob.cursor[0]*FONT_WIDTH, glob.cursor[1]*FONT_HEIGHT))
    screen.blit(dispfont.render(u"█", 1, (40, 255, 40)), (glob.cursor[0]*FONT_WIDTH, glob.cursor[1]*FONT_HEIGHT))
    glob.needFlip = True

def refreshScreen():
    """Clear and redraw the entire UI. Shouldn't need to be called often."""
    screen.fill(CBLACK)
    for y in range(0, 28):
        screen.blit(dispfont.render("|", 1, CWHITE), (FONT_WIDTH*DISP_WIDTH, y*FONT_HEIGHT))
        
def DEBUGMoveCursor(key):
    if key == UP_KEY:
        glob.cursor[1] -= 1
    elif key == DOWN_KEY:
        glob.cursor[1] += 1
    elif key == LEFT_KEY:
        glob.cursor[0] -= 1
    elif key == RIGHT_KEY:
        glob.cursor[0] += 1
    renderDisplay()
    if glob.cursor[0] >= DISP_WIDTH:
        sys.exit("STOP RIGHT THERE CRIMINAL SCUM")

textsize = dispfont.size("Connecting to server.") 
screen.blit(dispfont.render("Connecting to Server.", 1, (255, 255, 255)), (WINDOWSIZE[0]/2-textsize[0]/2, WINDOWSIZE[1]/2-textsize[1]/2))
pygame.display.flip()

shouldQuit = []
client = None
network = clientNetwork.connect("localhost", 1079)
network.addSystemEventTrigger('after', 'shutdown', shouldQuit.append, True)
network.run() #run gets 'crashed' as soon as the connection is successful. This is done so that twisted doesn't hog python.

refreshScreen()
pygame.display.flip()

while 1:
    TheClock.tick(30)
    for event in eventmodule.get():
        if event.type == QUIT:
            if client:
                client.transport.loseConnection()
                client = None
            if network._started:
                network.stop()
        elif event.type == KEYDOWN:
            if event.key == QUIT_KEY:
                if client:
                    client.transport.loseConnection()
                    client = None
                if network._started:
                    network.stop()
            else:
                DEBUGMoveCursor(event.key)
                if event.key == PLUS_KEY:
                    print 'plus key'
                    glob.camera[2] += 1
                    client.sendMessage(DISPLAY_REQUEST, "%+04d%+04d%+04d" % (glob.camera[0], glob.camera[1], glob.camera[2]))
                elif event.key == MINUS_KEY:
                    glob.camera[2] -= 1
                    client.sendMessage(DISPLAY_REQUEST, "%+04d%+04d%+04d" % (glob.camera[0], glob.camera[1], glob.camera[2]))
        elif event.type == USEREVENT:
            if event.code == CONNECTION_SUCCESS:
                client = event.data
            elif event.code == CONNECTION_FAILED:
                screen.fill(CBLACK)
                textsize = dispfont.size("Connection failed. Either your internet, or the server is down.") 
                screen.blit(dispfont.render("Connection failed. Either your internet, or the server is down.",
                                             1, (255, 255, 255)), (WINDOWSIZE[0]/2-textsize[0]/2, WINDOWSIZE[1]/2-textsize[1]/2))
                pygame.display.flip()
            elif event.code == CONNECTION_LOST:
                screen.fill(CBLACK)
                textsize = dispfont.size("Connection lost. Please reconnect.") 
                screen.blit(dispfont.render("Connection lost. Please reconnect.",
                                             1, (255, 255, 255)), (WINDOWSIZE[0]/2-textsize[0]/2, WINDOWSIZE[1]/2-textsize[1]/2))
                pygame.display.flip()
            elif event.code == DISPLAY_UPDATE:
                glob.currentDisplay = processRawDisplay(event.data)
                renderDisplay()
    network.iterate()
    if shouldQuit:
        break
    #Check if update needed
    #If so, ask server
    if glob.needFlip:
        pygame.display.flip()
        glob.needFlip = False

network = None
pygame.quit()
sys.exit(0)
